package com.koron.sinoprobe.web.ledger.service.impl;

import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.CodeTools;
import com.koron.sinoprobe.web.common.CommonUtils;
import com.koron.sinoprobe.web.engineering.service.SpEstablishService;
import com.koron.sinoprobe.web.ledger.bean.entity.SpProject;
import com.koron.sinoprobe.web.ledger.bean.entity.SpReport;
import com.koron.sinoprobe.web.ledger.bean.query.SpReportQuery;
import com.koron.sinoprobe.web.ledger.bean.vo.SpProjectVO;
import com.koron.sinoprobe.web.ledger.bean.vo.SpReportVO;
import com.koron.sinoprobe.web.ledger.bean.vo.SpendVO;
import com.koron.sinoprobe.web.ledger.mapper.SpReportMapper;
import com.koron.sinoprobe.web.ledger.service.SpProjectService;
import com.koron.sinoprobe.web.ledger.service.SpReportService;
import com.koron.sinoprobe.web.purchase.service.SpPurchaseEstablishService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author twcao
 * @title: SpReportServiceImpl
 * @projectName GDH_EAM_V2
 * @description: 项目汇报service实现
 * @date 2021/12/211:24
 */
@Service
public class SpReportServiceImpl implements SpReportService {

    @Autowired
    private SpProjectService projectService;

    @Autowired
    private SpEstablishService establishService;

    @Autowired
    private SpPurchaseEstablishService spPurchaseEstablishService;

    @Override
    @TaskAnnotation("queryById")
    public SpReport queryById(SessionFactory factory, String id) {
        SpReportMapper mapper = factory.getMapper(SpReportMapper.class);
        return mapper.queryById(id);
    }

    @Override
    @TaskAnnotation("queryList")
    public List<SpReportVO> queryList(SessionFactory factory, SpReportQuery query) {
        SpReportMapper mapper = factory.getMapper(SpReportMapper.class);
        return mapper.queryList(query);
    }

    @Override
    @TaskAnnotation("saveOrUpdate")
    public SpReport saveOrUpdate(SessionFactory factory, SpReport bean) {
        Assert.notNull(bean, "项目汇报不能为空");
        Assert.hasText(bean.getProjectId(), "项目id不能为空");
        Assert.hasText(bean.getMilestoneId(), "里程碑id不能为空");
        SpProjectVO spProjectVO = projectService.selectOne(factory, bean.getProjectId());
        String projectType = spProjectVO.getProjectType();
        // 未进行项目立项的采购类和工程类项目不允许更新进度
        if (bean.getProgress() > 0) {
            // 如果是工程类
            /*if ("project".equals(projectType)) {
                SpEstablish spEstablish = establishService.getByProjectId(factory, bean.getProjectId());
                if (spEstablish == null) {
                    throw new IllegalArgumentException("未进行工程项目立项，进度不能大于0");
                }
            }else if ("purchase".equals(projectType)) {
                // 如果是采购类
                SpPurchaseEstablish spPurchaseEstablish = spPurchaseEstablishService.getByProjectId(factory, bean.getProjectId());
                if (spPurchaseEstablish == null) {
                    throw new IllegalArgumentException("未进行采购项目立项，进度不能大于0");
                }
            }*/
        }
        spProjectVO.setProgress(bean.getProgress());
        spProjectVO.setAcceptCriteria(bean.getProgressStatus());
        spProjectVO.setUpdateFlag(bean.getUpdateFlag());
        // 只更新主体信息
        projectService.saveOrUpdate(factory, (SpProject) spProjectVO);
        CommonUtils.update(bean, ThreadLocalContext.get());
        bean.setId(StringUtils.isEmpty(bean.getId()) ? CodeTools.getCode32() : bean.getId());
        SpReportMapper mapper = factory.getMapper(SpReportMapper.class);
        mapper.saveOrUpdate(bean);
        return bean;
    }

    @Override
    @TaskAnnotation("deleteById")
    public String deleteById(SessionFactory factory, String id) {
        SpReportMapper mapper = factory.getMapper(SpReportMapper.class);
        mapper.deleteById(id);
        return id;
    }

    @Override
    @TaskAnnotation("getLatestReport")
    public SpReportVO getLatestReport(SessionFactory factory, String projectId) {
        SpReportMapper mapper = factory.getMapper(SpReportMapper.class);
        return mapper.getLatestReport(projectId);
    }

    @Override
    @TaskAnnotation("getReportSpend")
    public List<SpendVO> getReportSpend(SessionFactory factory, String projectId) {
        Assert.hasText(projectId, "项目id不能为空");
        SpReportMapper mapper = factory.getMapper(SpReportMapper.class);
        List<SpendVO> spends = new ArrayList<>();
        SpProjectVO spProjectVO = projectService.selectOne(factory, projectId);
        Assert.notNull(spProjectVO, "项目不存在");
        List<SpReportVO> reports = mapper.queryList(new SpReportQuery().setProjectId(projectId));
        Map<String, BigDecimal> spendMap = new HashMap<>();
        reports.stream().forEach(row -> {
            String year = DateFormatUtils.format(row.getCreateTime(), "yyyy");
            spendMap.put(year, spendMap.containsKey(year) ? spendMap.get(year).add(row.getInvestment()) : row.getInvestment());
        });
        BigDecimal total = new BigDecimal(0);
        Iterator<Map.Entry<String, BigDecimal>> iterator = spendMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, BigDecimal> next = iterator.next();
            total = total.add(next.getValue());
            spends.add(new SpendVO().setYear(next.getKey()).setSpend(next.getValue()));
        }
        if(!CollectionUtils.isEmpty(reports)) { //如果没有项目汇报，则不统计
            SpendVO totalVo = new SpendVO().setYear("总计").setSpend(total);
            if(!Objects.isNull(spProjectVO.getBudget())) { // 如果没有填预算，则不计算是否超支
                totalVo.setOverweight(total.compareTo(spProjectVO.getBudget()) > 0);
            }
            spends.add(totalVo);
        }
        return spends;
    }
}
